using System;
using Gtk;
using System.IO;

public class MainWindow: Gtk.Window
{
	//widgets
	protected Gtk.Button but_Modify;
	protected Gtk.ComboBox combo_existing_cat;
	protected Gtk.ComboBox combo_location;
	protected Gtk.Button but_add;
	protected Gtk.Entry entry_title;
	
	protected ListStore store_filenames;
	protected ListStore store;
	protected ListStore store2;
	
	public MainWindow (): base ("")
	{
		Stetic.Gui.Build (this, typeof(MainWindow));
		
		// store holds values
        store_filenames = new ListStore(typeof (string));
        store = new ListStore(typeof (string));
        store2 = new ListStore(typeof (string));
        
		init_widgets();
	}
	
	protected void init_widgets() {
		TextReader categ;
    	try {
      		categ = new StreamReader("categories.txt"); // config file to read from 
    	} catch(FileNotFoundException exc) {
      		Console.WriteLine(exc.Message); 
      		return; 
    	}
    	
    	// initialize for combo_box
    	CellRendererText cell = new CellRendererText();
        
        // erase old data
        store.Clear();
        store.Clear();
        store_filenames.Clear();
        
        // initialize modify/delete existing category
        combo_existing_cat.Clear();
    	combo_existing_cat.PackStart(cell, false);
        combo_existing_cat.AddAttribute(cell, "text", 0);
        
        // initialize new category location
        combo_location.Clear();
    	combo_location.PackStart(cell, false);
        combo_location.AddAttribute(cell, "text", 0);
        
        // assign stores
        combo_existing_cat.Model = store;
        combo_location.Model = store2;
        
        // populate stores into combo box
    	while (categ.Peek() != -1) {
    		String temp = categ.ReadLine();
    		store_filenames.AppendValues(0,temp.IndexOf(' '));
			temp = temp.Substring(temp.IndexOf(' ')+1);
			store.AppendValues(temp.Substring(0,temp.Length));
    		store2.AppendValues("\n");
    		store2.AppendValues(temp.Substring(0,temp.Length));
    	}
    	store2.AppendValues("\n");
		categ.Close();
		
		// set combo boxes to have initial active item
		combo_existing_cat.Active = 0;
		combo_location.Active = 0;
		
		// clear textbox
		entry_title.DeleteText(0, entry_title.Text.Length);
    }
	protected void OnDeleteEvent (object sender, DeleteEventArgs a)
	{
		Application.Quit ();
		a.RetVal = true;
	}

	protected virtual void but_add_clicked(object sender, System.EventArgs e)
	{
		// category filename cannot have ' ' in it.  We use ' ' to find when category filename ends
		
		//  If no text is in title, halt adding.
		if (entry_title.Text.Trim() == "") {
			MessageDialog md = new MessageDialog (this,
									DialogFlags.DestroyWithParent,
                                   MessageType.Error, 
                                      ButtonsType.Close, "Category must have a title.");
     
			int result = md.Run ();
			md.Destroy();
			return;
		}
		
		//  If location is not empty space, cannot overwrite another page as location
		if (combo_location.ActiveText.Trim() != "") {
			MessageDialog md = new MessageDialog (this,
									DialogFlags.DestroyWithParent,
                                   MessageType.Error, 
                                      ButtonsType.Close, "Select a location above or below the selected page.");
     
			int result = md.Run ();
			md.Destroy();
			return;
		}
		
		// write to file to add new one
		TextReader infile;// infile is page ( category --> page )
		try {
 			infile = new StreamReader("categories.txt"); // file to read from 
    	} catch(FileNotFoundException exc) { 
      		Console.WriteLine(exc.Message); 
      		return; 
    	}

		FileStream outfile; // file to write to
		try {
			outfile = new FileStream("categories_new.txt", FileMode.OpenOrCreate, FileAccess.Write);
		} catch(UnauthorizedAccessException exc) {
			Console.WriteLine(exc.Message);
			return;
		}
		
		// Create a new stream to write to the file
		StreamWriter sw = new StreamWriter(outfile);
		
		// new position: 0=before 1, 2=before 2, 4=before3,6=before4
		// algorithm: selected/2
		int new_location = combo_location.Active/2;
        int line_count = 0;
        String temp_entry = entry_title.Text;// temp_entry will be filename-extension
        String entry = "cat_";
      	temp_entry = entry_title.Text.Trim();
      	temp_entry = temp_entry.ToLower();
      	temp_entry = temp_entry.Replace(" ","");
      	if (temp_entry.Length > 6)
      		temp_entry = temp_entry.Substring(0, 6);
      	entry += temp_entry + ".txt " + entry_title.Text;
      	
        while (infile.Peek() != -1) // are there any more lines in categories.txt
		{
			String temp = infile.ReadLine();// save line
			if (line_count == new_location) {
				// write the new category that user inputted
				sw.WriteLine(entry);
			} 
			// write existing categories in
			sw.WriteLine(temp);
			line_count++;// keep track of which line we're on to insert new category
		}
		infile.Close();
		sw.Close();
		outfile.Close();

		File.Delete("categories.txt");
		File.Move("categories_new.txt","categories.txt");

		//==============================================
		// now insert category correctly into dynamic.js
		//==============================================
		try {
 			infile = new StreamReader("dynamic.js"); // file to read from 
    	} catch(FileNotFoundException exc) {
      		Console.WriteLine(exc.Message);
      		return;
    	}

		try {
			outfile = new FileStream("dynamic.js.backup", FileMode.OpenOrCreate, FileAccess.Write);
		} catch(UnauthorizedAccessException exc) {
			Console.WriteLine(exc.Message);
			return;
		}
		
		// Create a new stream to write to the file
		sw = new StreamWriter(outfile);
		
		int i=0;// category counter
		int location=combo_location.Active/2;
		bool found=false;
        while (infile.Peek() != -1) { // reading file to write in formatted html to file
			String line = infile.ReadLine();
			//Console.WriteLine(line);
			if (line.StartsWith("document.writeln('  <li id=\"nav-")) {
				// category found
				//Console.WriteLine("Category found!");
				if (i==location) {
					//Console.WriteLine("Found new location");
					// new category's position, insert
					// write (i+1) since html/css file starts counting at 1, not 0.
					sw.WriteLine("document.writeln('  <li id=\"nav-"+(i+1)+"\"><a href=\""+"cat_"+temp_entry+"\">"+entry_title.Text+"</a></li>');");
					sw.WriteLine("document.writeln('    <ul id=\"subnav-"+(i+1)+"\">');");
					sw.WriteLine("document.writeln('    </ul>');");
					sw.WriteLine("document.writeln('  </li>');");
					i++;
					found=true;
					//Console.WriteLine(i);
				}
				
				if (found) {
				// insert has occured, change following categories
					// insert existing category
					line=line.Remove(32,1);// remove nav#
					line=line.Insert(32,(i+1).ToString());// insert new nav#
					//Console.WriteLine(line);
					sw.WriteLine(line);// writing new existing category li tag
					
					// now we must change the subnav # as well, which is always the next line
					line=infile.ReadLine();
					line=line.Remove(37,1);
					line=line.Insert(37,(i+1).ToString());
					//Console.WriteLine(line);
					sw.WriteLine(line);
					
					// Changing each page's section # to correspond to new insert
					line=infile.ReadLine(); 
					while (!line.Equals("document.writeln('    </ul>');")) {
						// line is a page in the category
						//Console.WriteLine(line);
						TextReader infile_page;// infile is page ( category --> page )
						try {
							string page_filename=line.Substring(37,line.LastIndexOf("\"")-37);
							//Console.WriteLine(page_filename);
							infile_page = new StreamReader(page_filename); // file to read from
							FileStream outfile_page; // file to write to
							try {
								outfile_page = new FileStream(page_filename+".backup", FileMode.OpenOrCreate, FileAccess.Write);
								StreamWriter sw_page = new StreamWriter(outfile_page);
								
								// find and replace in each page the section # with new section #
								// only if the new category has been inserted
								while ((infile_page.Peek() != -1) && (found)) {
									// reading file to write in formatted html to file
									String temp = infile_page.ReadLine();
									//Console.WriteLine(temp);
									if (temp.StartsWith("<body class=\"section-"))// this is the line with section #
										temp="<body class=\"section-"+(i+1).ToString()+"\">";
									sw_page.WriteLine(temp);
								}
								infile_page.Close();
								sw_page.Close();
								outfile_page.Close();
								
								File.Delete(page_filename);
								File.Move(page_filename+".backup",page_filename);
							} catch(UnauthorizedAccessException exc) {
								// could not write to file, still have read file open
								infile_page.Close();
								Console.WriteLine(exc.Message);
							}				
				    	} catch(FileNotFoundException exc) {
				    		// could not open read file
				      		Console.WriteLine(exc.Message); 
				    	}
				    	sw.WriteLine(line);
				    	line=infile.ReadLine();// get next line, test for page or end of category
					}
					// now we are at "document.writeln('    </ul>');" line.
				} else {
					while (!line.Equals("document.writeln('    </ul>');")) {
						sw.WriteLine(line);
						line=infile.ReadLine();
					}	
				}
				i++;// increase category count
				//Console.WriteLine(i);
			}
			//Console.WriteLine(line);
			sw.WriteLine(line);
		}
		infile.Close();
		sw.Close();
		outfile.Close();

		File.Delete("dynamic.js");
		File.Move("dynamic.js.backup","dynamic.js");
		
		//==============================================
		// now insert category correctly into tab.css
		//==============================================
		try {
 			infile = new StreamReader("tab.css"); // file to read from 
    	} catch(FileNotFoundException exc) {
      		Console.WriteLine(exc.Message);
      		return;
    	}

		try {
			outfile = new FileStream("tab.css.backup", FileMode.OpenOrCreate, FileAccess.Write);
		} catch(UnauthorizedAccessException exc) {
			Console.WriteLine(exc.Message);
			return;
		}
		
		// Create a new stream to write to the file
		sw = new StreamWriter(outfile);
		
        while (infile.Peek() != -1) { // reading file to write in formatted html to file
			String line = infile.ReadLine();
			string newline="";
			if (line.StartsWith("  body.section-1 #menu li#nav-1 a")) {
				// i is # of categories from adding into dynamic.js
				newline = " ";
				for (int j=0; j<i; j++) 
					newline +=" body.section-" + (j+1).ToString() +" #menu li#nav-" + (j+1).ToString() + " a,";
				newline=newline.Remove(newline.Length-1, 1) + " {";
				sw.WriteLine(newline);
			} else if (line.StartsWith("  #menu #subnav-1")) { 
				// i is # of categories from adding into dynamic.js
				newline = " ";
				for (int j=0; j<i; j++)
					newline +=" #menu #subnav-" + (j+1).ToString() +",";
				newline=newline.Remove(newline.Length-1, 1) + " {";
				sw.WriteLine(newline);
			} else if (line.StartsWith("  body.section-1 #menu ul#subnav-1 a")) { 
				// i is # of categories from adding into dynamic.js
				newline = " ";
				for (int j=0; j<i; j++)
					newline +=" body.section-" + (j+1).ToString() + " #menu ul#subnav-" + (j+1).ToString() +" a,";
				newline=newline.Remove(newline.Length-1, 1) + " {";
				sw.WriteLine(newline);
			} else if (line.StartsWith("  body.section-1 #menu ul#subnav-1")) { 
				// i is # of categories from adding into dynamic.js
				newline = " ";
				for (int j=0; j<i; j++)
					newline +=" body.section-" + (j+1).ToString() + " #menu ul#subnav-" + (j+1).ToString() +",";
				newline=newline.Remove(newline.Length-1, 1) + " {";
				sw.WriteLine(newline);
			} else {
				sw.WriteLine(line);
			}
		}
		
		infile.Close();
		sw.Close();
		outfile.Close();

		File.Delete("tab.css");
		File.Move("tab.css.backup","tab.css");
		
		init_widgets();
	}

	protected virtual void OnButModifyClicked(object sender, System.EventArgs e)
	{
		//  Since I'm not sure how to use ListStore, I'm going to read in again
		//  the correct filename that needs to be sent to be read for the
		//  category to be modified.
		
		String filename="";// filename
		
		// open file
		TextReader categ;
    	try {
      		categ = new StreamReader("categories.txt"); // config file to read from 
    	} catch(FileNotFoundException exc) { 
      		Console.WriteLine(exc.Message); 
      		return; 
    	}
    	
    	// read until we hit filename
    	for (int i=0; i<=combo_existing_cat.Active; i++) {
    		filename = categ.ReadLine();
    		filename = filename.Substring(0,filename.IndexOf(' '));
    	}
    	categ.Close();
    	
		// send category's filename, category's title and category #
		// reason why category # has +1 is because the html code starts counting at 1, not 0.
		new wc_gui_input.list_pages(filename, combo_existing_cat.ActiveText, combo_existing_cat.Active+1);
	}

	protected virtual void OnButDeleteClicked(object sender, System.EventArgs e)
	{
		TextReader infile;// infile is page ( category --> page )
		try {
 			infile = new StreamReader("categories.txt"); // file to read from 
    	} catch(FileNotFoundException exc) { 
      		Console.WriteLine(exc.Message); 
      		return; 
    	}

		FileStream outfile; // file to write to
		try {
			outfile = new FileStream("categories_new.txt", FileMode.OpenOrCreate, FileAccess.Write);
		} catch(UnauthorizedAccessException exc) {
			Console.WriteLine(exc.Message);
			return;
		}
		
		// Create a new stream to write to the file
		StreamWriter sw = new StreamWriter(outfile);

        int line_count = 0;
        while (infile.Peek() != -1) // reading file to write in formatted html to file
		{
			String temp = infile.ReadLine();
			if (line_count != combo_existing_cat.Active) {
				// skip writing the category that user selected
				sw.WriteLine(temp);
			}
			line_count++;// increase # to append next template text file
		}
		infile.Close();
		sw.Close();
		outfile.Close();

		File.Delete("categories.txt");
		File.Move("categories_new.txt","categories.txt");

		//==============================================
		// now remove category correctly from dynamic.js
		//==============================================
		try {
 			infile = new StreamReader("dynamic.js"); // file to read from 
    	} catch(FileNotFoundException exc) {
      		Console.WriteLine(exc.Message);
      		return;
    	}

		try {
			outfile = new FileStream("dynamic.js.backup", FileMode.OpenOrCreate, FileAccess.Write);
		} catch(UnauthorizedAccessException exc) {
			Console.WriteLine(exc.Message);
			return;
		}
		
		// Create a new stream to write to the file
		sw = new StreamWriter(outfile);
		
		int i=0;// category counter
		int location=combo_existing_cat.Active;// category to delete is in the list of existing categories
		bool found=false;
        while (infile.Peek() != -1) { // reading file to write in formatted html to file
			String line = infile.ReadLine();
			//Console.WriteLine(line);
			if (line.StartsWith("document.writeln('  <li id=\"nav-")) {
				// category found
				//Console.WriteLine("Category found!");
				if (i==location) {
					//Console.WriteLine("Found category to delete");
					// category to delete's position, remove
					 while (line != "document.writeln('  </li>');") {
						line = infile.ReadLine();
						if (line.StartsWith("document.writeln('      <li><a href=")) {
							string page_filename=line.Substring(37,line.LastIndexOf("\"")-37);
							//Console.WriteLine(page_filename);
							try {
								File.Delete(page_filename);
							} catch(FileNotFoundException exc) {
				    			// could not open file
				      			Console.WriteLine(exc.Message); 
				    		}
						}
					}
					// on last line of category, get to next line
					// can't assume there will be another category (what if user deleted last one)
					
					line = infile.ReadLine();
					found=true;
					//Console.WriteLine(i);
					//Console.WriteLine("end of removal: " + line);
				}
				
				if (found & line !="document.writeln('</ul>');") {
				// have to test for line due to may be last category
				// deletion occured, changes must be made to category #
					//Console.WriteLine("Change: " + line);
					// write existing category
					line=line.Remove(32,1);// remove nav#
					line=line.Insert(32,(i+1).ToString());// insert new nav#
					//Console.WriteLine("Changing category: " + line);
					sw.WriteLine(line);// writing new existing category li tag
					
					// now we must change the subnav # as well, which is always the next line
					line=infile.ReadLine();
					line=line.Remove(37,1);
					line=line.Insert(37,(i+1).ToString());
					//Console.WriteLine("Changing subcategory: " + line);
					sw.WriteLine(line);
					
					// Changing each page's section # to correspond to removal of category
					line=infile.ReadLine(); 
					while (!line.Equals("document.writeln('    </ul>');")) {
						// line is a page in the category
						//Console.WriteLine("Start of while loop: " + line);
						TextReader infile_page;// infile is page ( category --> page )
						try {
							string page_filename=line.Substring(37,line.LastIndexOf("\"")-37);
							//Console.WriteLine("page filename: " + page_filename);
							//Console.WriteLine(page_filename);
							infile_page = new StreamReader(page_filename); // file to read from
							FileStream outfile_page; // file to write to
							try {
								outfile_page = new FileStream(page_filename+".backup", FileMode.OpenOrCreate, FileAccess.Write);
								StreamWriter sw_page = new StreamWriter(outfile_page);
								
								// find and replace in each page the section # with new section #
								// only if the new category has been inserted
								while ((infile_page.Peek() != -1) && (found)) {
									// reading file to write in formatted html to file
									String temp = infile_page.ReadLine();
									//Console.WriteLine(temp);
									if (temp.StartsWith("<body class=\"section-"))// this is the line with section #
										temp="<body class=\"section-"+(i+1).ToString()+"\">";
									sw_page.WriteLine(temp);
								}
								infile_page.Close();
								sw_page.Close();
								outfile_page.Close();
								
								File.Delete(page_filename);
								File.Move(page_filename+".backup",page_filename);
							} catch(UnauthorizedAccessException exc) {
								// could not write to file, still have read file open
								infile_page.Close();
								Console.WriteLine(exc.Message);
							}				
				    	} catch(FileNotFoundException exc) {
				    		// could not open read file
				      		Console.WriteLine(exc.Message); 
				    	}
				    	sw.WriteLine(line);
				    	line=infile.ReadLine();// get next line, test for page or end of category
					}
				}
				
				i++;// increase category count
				//Console.WriteLine(i);
			}
			//Console.WriteLine("last write: " + line);
			sw.WriteLine(line);
		}
		infile.Close();
		sw.Close();
		outfile.Close();

		File.Delete("dynamic.js");
		File.Move("dynamic.js.backup","dynamic.js");
		

		init_widgets();
	}
}